using System;
using Unity.Mathematics;
using UnityEngine;

[Serializable]
public class CompressedProbeData : ScriptableObject
{
    public Vector3[] positions;
    public float[] mean;                // 27
    public Float2DArray pcaAxes;        // components x 27
    public Float2DArray coefficients;    // probeCount x components

    public bool IsValid()
    {
        return positions != null && positions.Length > 0 &&
               mean != null && mean.Length > 0 &&
               pcaAxes != null /*&& pcaAxes.Length > 0*/ &&
               coefficients != null;// && coefficients.Length > 0;
    }
}

[Serializable]
public class Float2DArray
{
    [SerializeField]
    private int rows;
    [SerializeField]
    private int cols;
    [SerializeField]
    private float[] data;

    public Float2DArray(int rows, int cols)
    {
        this.rows = rows;
        this.cols = cols;
        data = new float[rows * cols];
    }

    public Float2DArray(float[,] array)
    {
        rows = array.GetLength(0);
        cols = array.GetLength(1);
        data = new float[rows * cols];
        for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++)
            this[r, c] = array[r, c];
    }
    
    public float this[int row, int col]
    {
        get => data[row * cols + col];
        set => data[row * cols + col] = value;
    }

    public int RowCount => rows;
    public int ColCount => cols;

    public float[,] To2DArray()
    {
        float[,] result = new float[rows, cols];
        for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++)
            result[r, c] = this[r, c];
        return result;
    }

    public void From2DArray(float[,] array)
    {
        rows = array.GetLength(0);
        cols = array.GetLength(1);
        data = new float[rows * cols];
        for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++)
            this[r, c] = array[r, c];
    }
}

[Serializable]
public class Half2DArray
{
    [SerializeField]
    private int rows;
    [SerializeField]
    private int cols;
    [SerializeField]
    private half[] data;

    public Half2DArray(int rows, int cols)
    {
        this.rows = rows;
        this.cols = cols;
        data = new half[rows * cols];
    }

    public Half2DArray(float[,] array)
    {
        rows = array.GetLength(0);
        cols = array.GetLength(1);
        data = new half[rows * cols];
        for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++)
        {
            float f = Mathf.Round(array[r, c] * Mathf.Pow(10, 3)) / Mathf.Pow(10, 3);
            half h = (half)f;
           

            this[r, c] = h;
        }
          
    }
    
    public half this[int row, int col]
    {
        get => data[row * cols + col];
        set => data[row * cols + col] = value;
    }

    public int RowCount => rows;
    public int ColCount => cols;

    public float[,] To2DArray()
    {
        float[,] result = new float[rows, cols];
        for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++)
            result[r, c] = this[r, c];
        return result;
    }

    public void From2DArray(half[,] array)
    {
        rows = array.GetLength(0);
        cols = array.GetLength(1);
        data = new half[rows * cols];
        for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++)
            this[r, c] = array[r, c];
    }
}